/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package model;

import abstractmodel.AccountType;
import abstractmodel.IAccount;
import abstractmodel.IBook;
import abstractmodel.IDetail;
import abstractmodel.IUser;
import configure.ConfigureInfo;
import dataaccess.DataSourceFactory;
import dataaccess.IDataSource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author littlechild
 */
public class ModelFactory implements abstractmodel.IModelFactory {

    static int maxid = Integer.parseInt(ConfigureInfo.getProperty(ConfigureInfo.Maxid));
    static IDataSource data;
    static IUser ur=null;

    public ModelFactory() {
        //load信息，初始化数据
        try {
            data = DataSourceFactory.getDataSource(ConfigureInfo.getProperty(ConfigureInfo.DataSourceClassName));
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ModelFactory.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(ModelFactory.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(ModelFactory.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public IUser getUser(String name, String password) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(password.getBytes());
            MessageDigest change = (MessageDigest) md.clone();
            byte[] changeBytes = change.digest();
            String md5Password = new String(Arrays.toString(changeBytes));
            if (md5Password == null) {
            } else if (md5Password.equals(data.loadLogInInfo().get(name))) {
                ur=data.loadUser(name);
                return ur;
            }
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(ModelFactory.class.getName()).log(Level.SEVERE, null, ex);
        } catch (CloneNotSupportedException ex) {
            Logger.getLogger(ModelFactory.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    @Override
    public IUser newUser(String name, String password) {
        User user = new User();
        ur=user;
        try {
            ID.incID();
            user.getUserInfo().setId(ID.getID());
            Map map = data.loadLogInInfo();
            /**
             * 用md5算法进行加密处理
             */
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(password.getBytes());
            MessageDigest change = (MessageDigest) md.clone();
            byte[] changeBytes = change.digest();
            String md5Password = new String(Arrays.toString(changeBytes));
            map.put(name, md5Password);
            data.saveLogInInfo(map);
            user.getUserInfo().setValue("用户名", name);
            user.getUserInfo().setValue("密码", md5Password);
        } catch (Exception ex) {
            System.out.println("Exception in ModelFactory of newUser");
        }
        IBook book = newBook();
        IAccount account1 = newAccount(AccountType.BANK_ACCOUNT_TYPE);
        book.addNewAccount(account1);
        IAccount account2 = newAccount(AccountType.CREDITCARD_ACCOUNT_TYPE);
        book.addNewAccount(account2);
        IAccount account3 = newAccount(AccountType.MONEY_ACCOUNT_TYPE);
        book.addNewAccount(account3);
        user.addNewBook(book);
        user.commit();
        return user;
        
    }

    @Override
    public IBook newBook() {
        Book book = new Book();
        ID.incID();
        book.getBookInfo().setId(ID.getID());
        return new Book();
    }

    @Override
    public IAccount newAccount(AccountType accountType) {
        if (accountType == abstractmodel.AccountType.BANK_ACCOUNT_TYPE) {
            IAccount account = new model.BankAccount();
            ID.incID();
            account.getAccountInfo().setId(ID.getID());
            return account;
        } else if (accountType == abstractmodel.AccountType.CREDITCARD_ACCOUNT_TYPE) {
            IAccount account = new model.CreditCardAccount();
            ID.incID();
            account.getAccountInfo().setId(ID.getID());
            return account;
        } else if (accountType == abstractmodel.AccountType.MONEY_ACCOUNT_TYPE) {
            IAccount account = new model.MoneyAccount();
            ID.incID();
            account.getAccountInfo().setId(ID.getID());
            return account;
        }
        return null;    //非这三种类型，出错，返回null
    }

    /**
     * 
     * @param account：根据帐户类型生成相应的明细类型
     * @return 相应的明细类
     */
    @Override
    public IDetail newDetail(IAccount account) {
        Detail detail = new Detail(account);
        if (account instanceof BankAccount) {
            BankDetailInfo bd = new BankDetailInfo();
            bd.setParentID(account.getAccountInfo().getid());
            ID.incID();
            bd.setId(ID.getID());
            bd.setValue("余额", 0);
            detail.setDetailInfo(bd);        
            return detail;
        } else if (account instanceof CreditCardAccount) {
            CreditCardDetailInfo ccd = new CreditCardDetailInfo();
            ccd.setParentID(account.getAccountInfo().getid());
            ID.incID();
            ccd.setId(ID.getID());
            ccd.setValue("余额", 0);
            detail.setDetailInfo(ccd);
            return detail;
        } else if (account instanceof MoneyAccount) {
            MoneyDetailInfo md = new MoneyDetailInfo();
            md.setParentID(account.getAccountInfo().getid());
            ID.incID();
            md.setId(ID.getID());
            md.setValue("余额", 0);
            detail.setDetailInfo(md);
             return detail;
        }
        return null;
    }

    @Override
    public String[] getAllUserName() {
        Set<String> nameSet = data.loadLogInInfo().keySet();
        String[] nameString = new String[nameSet.size()];
        int i = 0;
        for (Iterator it = nameSet.iterator(); it.hasNext();) {
            nameString[i] = it.next().toString();
            i++;
        }
        return nameString;
    }

    @Override
    public boolean deleteUser(IUser user) {
        if (data.deleteUser(user))
            return true;
        else 
            return false;
    }
}
